package com.micro.ai.models.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.models.entity.TrainingCheckpoint;
import com.micro.ai.models.mapper.TrainingCheckpointMapper;
import com.micro.ai.models.service.TrainingCheckpointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 训练检查点服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class TrainingCheckpointServiceImpl extends ServiceImpl<TrainingCheckpointMapper, TrainingCheckpoint> implements TrainingCheckpointService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TrainingCheckpoint create(TrainingCheckpoint checkpoint) {
        if (checkpoint == null) {
            throw new BusinessException("M0000", "检查点信息不能为空");
        }
        
        if (checkpoint.getCreatedAt() == null) {
            checkpoint.setCreatedAt(LocalDateTime.now());
        }
        
        boolean success = this.save(checkpoint);
        if (!success) {
            throw new BusinessException("M0003", "保存检查点失败");
        }
        
        log.info("创建检查点成功: checkpointId={}, checkpointName={}, jobId={}", 
                checkpoint.getId(), checkpoint.getCheckpointName(), checkpoint.getJobId());
        return checkpoint;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TrainingCheckpoint update(String id, TrainingCheckpoint checkpoint) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "检查点ID不能为空");
        }
        if (checkpoint == null) {
            throw new BusinessException("M0000", "检查点信息不能为空");
        }
        
        TrainingCheckpoint existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("M0002", "检查点不存在: " + id);
        }
        
        checkpoint.setId(id);
        
        boolean success = this.updateById(checkpoint);
        if (!success) {
            throw new BusinessException("M0003", "更新检查点失败");
        }
        
        log.info("更新检查点成功: checkpointId={}", id);
        return checkpoint;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "检查点ID不能为空");
        }
        
        TrainingCheckpoint checkpoint = this.getById(id);
        if (checkpoint == null) {
            throw new BusinessException("M0002", "检查点不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("M0003", "删除检查点失败");
        }
        
        log.info("删除检查点成功: checkpointId={}, checkpointName={}", id, checkpoint.getCheckpointName());
    }

    @Override
    public TrainingCheckpoint getById(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "检查点ID不能为空");
        }
        
        TrainingCheckpoint checkpoint = super.getById(id);
        if (checkpoint == null) {
            throw new BusinessException("M0002", "检查点不存在: " + id);
        }
        
        return checkpoint;
    }

    @Override
    public Page<TrainingCheckpoint> listByJobId(String jobId) {
        if (!StringUtils.hasText(jobId)) {
            throw new BusinessException("M0000", "任务ID不能为空");
        }
        
        LambdaQueryWrapper<TrainingCheckpoint> query = new LambdaQueryWrapper<>();
        query.eq(TrainingCheckpoint::getJobId, jobId)
             .orderByDesc(TrainingCheckpoint::getEpoch)
             .orderByDesc(TrainingCheckpoint::getStep);
        
        return this.page(new Page<>(1, 100), query);
    }

    @Override
    public TrainingCheckpoint getBest(String jobId) {
        if (!StringUtils.hasText(jobId)) {
            throw new BusinessException("M0000", "任务ID不能为空");
        }
        
        LambdaQueryWrapper<TrainingCheckpoint> query = new LambdaQueryWrapper<>();
        query.eq(TrainingCheckpoint::getJobId, jobId)
             .eq(TrainingCheckpoint::getIsBest, true)
             .orderByDesc(TrainingCheckpoint::getCreatedAt)
             .last("LIMIT 1");
        
        return this.getOne(query);
    }
}

